import random
import uuid
import base64
from io import BytesIO
from PIL import Image, ImageDraw, ImageFont
from django.conf import settings
from django_redis import get_redis_connection


def generate_captcha():
    """
    生成验证码图片，并将答案存入 Redis
    返回包含 captchaKey 和 captchaBase64 的字典
    """
    # 从 settings 获取配置
    captcha_type = getattr(settings, "CAPTCHA_TYPE", "arithmetic")
    captcha_timeout = getattr(settings, "CAPTCHA_TIMEOUT", 300)
    font_path = getattr(settings, "CAPTCHA_FONT_PATH", "arial.ttf")
    interference = getattr(settings, "CAPTCHA_INTERFERENCE", 5)

    # 初始化答案变量
    answer = ""

    # 根据验证码类型生成表达式和答案
    if captcha_type == "arithmetic":
        operators = ['+', '-', '*', '/']
        operator = random.choice(operators)
        if operator == '/':
            # 确保整除：选择除数和商，计算被除数
            b = random.randint(1, 10)
            quotient = random.randint(1, 10)
            a = b * quotient
            expression = f"{a}{operator}{b}="
            answer = str(quotient)
        else:
            a = random.randint(1, 20)
            b = random.randint(1, 20)
            expression = f"{a}{operator}{b}="
            if operator == '+':
                answer = str(a + b)
            elif operator == '-':
                answer = str(a - b)
            elif operator == '*':
                answer = str(a * b)
    else:
        # 字母数字验证码，生成6位随机字符（不区分大小写）
        chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        expression = ''.join(random.choices(chars, k=6))
        answer = expression.lower()

    # 创建验证码图片
    width, height = 120, 40  # 图片尺寸，可根据需求调整
    image = Image.new('RGB', (width, height), (255, 255, 255))
    draw = ImageDraw.Draw(image)
    try:
        font = ImageFont.truetype(font_path, 24)
    except OSError:
        # 如果加载字体失败，使用默认字体
        font = ImageFont.load_default()

    # 使用 textbox 获取文字的边界框，计算文字宽度和高度
    bbox = draw.textbbox((0, 0), expression, font=font)
    text_width = bbox[2] - bbox[0]
    text_height = bbox[3] - bbox[1]
    text_x = (width - text_width) / 2
    text_y = (height - text_height) / 2

    # 生成随机文本颜色，确保颜色随机变化
    text_color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    draw.text((text_x, text_y), expression, font=font, fill=text_color)

    # 添加干扰线（随机颜色）
    for _ in range(interference):
        start = (random.randint(0, width), random.randint(0, height))
        end = (random.randint(0, width), random.randint(0, height))
        line_color = (
            random.randint(0, 255),
            random.randint(0, 255),
            random.randint(0, 255)
        )
        draw.line([start, end], fill=line_color, width=1)
    # 添加干扰点（随机颜色）
    for _ in range(interference * 10):
        point = (random.randint(0, width), random.randint(0, height))
        point_color = (
            random.randint(0, 255),
            random.randint(0, 255),
            random.randint(0, 255)
        )
        draw.point(point, fill=point_color)

    # 将图片保存到内存并转为 Base64 编码
    buffered = BytesIO()
    image.save(buffered, format="PNG")
    img_base64 = base64.b64encode(buffered.getvalue()).decode('utf-8')
    captcha_base64 = f"data:image/png;base64,{img_base64}"

    # 生成唯一的 captchaKey，并将答案存入 Redis
    captcha_key = uuid.uuid4().hex
    redis_conn = get_redis_connection("default")
    redis_conn.setex(captcha_key, captcha_timeout, answer)

    return {
        "captchaKey": captcha_key,
        "captchaBase64": captcha_base64
    }
